/*
 * @(#)SystemMonitorFilter.java
 *
 * Copyright (c) 2003 DCIVision Ltd
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of DCIVision
 * Ltd ("Confidential Information").  You shall not disclose such Confidential
 * Information and shall use it only in accordance with the terms of the license
 * agreement you entered into with DCIVision Ltd.
 */
package com.dcivision.framework.web; 

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.impl.LogFactoryImpl;

/**
 * Filter to monitor JVM memory usage
 * it logs the information into a common logger (default: MemoryLog.txt)
 * 
 * @author Ryan Kwan
 * @company DCIVision Limited
 * @creation date 18/03/2005
 * @version $Revision: 1.5 $
 */
public class SystemMonitorFilter implements Filter {

  public static final String REVISION = "$Revision: 1.5 $";

  private static final String DEBUG_LEVEL = "debug_level";

  private int debugLevel=0;

  protected Log logger = new LogFactoryImpl().getInstance(this.getClass());

  /**
   * Take this filter out of service.
   */
  public void destroy() {
	
  }

  /**
   * Select and set (if specified) the character encoding to be used to
   * interpret request parameters for this request.
   *
   * @param request The servlet request we are processing
   * @param result The servlet response we are creating
   * @param chain The filter chain we are processing
   *
   * @exception IOException if an input/output error occurs
   * @exception ServletException if a servlet error occurs
   */
  public void doFilter(ServletRequest request,ServletResponse response,FilterChain chain) throws IOException, ServletException {
    try{      

      //skip logging if debug level = 0
      if(debugLevel>0) logSystemStatus(true, request);

      chain.doFilter(request, response);

      //skip logging if debug level = 0
      if(debugLevel>0) logSystemStatus(false, request);

    }catch(Exception e){
	logger.error("Exception found from parent chain:"+e.getMessage());
	throw new IOException(e.getMessage());
    }
  }

  /**
   * Log the system memory status
   * @param isBeforeChain	to mark this call is log before or after the request
   * @param request		the coming request being call or just call
   */
  protected void logSystemStatus(boolean isBeforeChain, ServletRequest request){
    Runtime runtime = Runtime.getRuntime();

    long maxMemory=0;
    long totalMemory=0;
    long freeMemory = runtime.freeMemory();

    //only capture max and total memory if debug level > 1
    if(debugLevel > 1){
      maxMemory = runtime.maxMemory();
      totalMemory = runtime.totalMemory();
    }

    String url = ((HttpServletRequest)request).getRequestURI();
    StringBuffer buffer  = new StringBuffer();

    if(isBeforeChain){
      buffer.append("Entering");
    }else{
      buffer.append("Leaving");
    }

    buffer.append(" URL: " + url);
    buffer.append(", Free Mem: ").append(freeMemory);

    //only capture max and total memory if debug level > 1
    if(debugLevel > 1){
      buffer.append(", Max Mem: ").append(maxMemory);
      buffer.append(", Total Mem: ").append(totalMemory);
    }

    logger.debug(buffer);
  }


  /**
   * Place this filter into service.
   * @param filterConfig The filter configuration object
   */
  public void init(FilterConfig filterConfig) throws ServletException {
    String debugLevelStr = filterConfig.getInitParameter(DEBUG_LEVEL);
    debugLevel = Integer.parseInt(debugLevelStr);
  }
}